﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media.Animation;
using System.Windows.Threading;
using MouseExtender.Logic;
using MouseExtender.Logic.Common;
using MouseExtender.Logic.Entities;
using MouseExtender.Logic.Enums;
using MouseExtender.Logic.Managers;
using MouseExtender.Resources;

namespace MouseExtender.Controls.UserControls
{
    /// <summary>
    /// Interaction logic for SystemButtonsBarUC.xaml
    /// </summary>
    public partial class SystemButtonsBarUC : UserControl
    {
        DispatcherTimer _takeAnActionTimer;
        TimeSpan? _timeSpanToAct = null;
        private List<int> _timerScalePeriods = new List<int>() { 1, 60, 600, 1440 };
        private TimerScalePeriod _currentScale = TimerScalePeriod.Hour;


        public SystemButtonsBarUC()
        {
            InitializeComponent();
        }

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            //initialize control here
            _takeAnActionTimer = new DispatcherTimer();
            _takeAnActionTimer.Interval = TimeSpan.FromSeconds(1);
            _takeAnActionTimer.Tick += new EventHandler(_hibernateTimer_Tick);
        }

        private void btnControlPanel_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            MainWindow mainWindow = (MainWindow)Application.Current.MainWindow;
            mainWindow.HideWindow();
            ProcessStartInfo startInfo = new ProcessStartInfo("control");
            Process.Start(startInfo);
        }

        private void btnReboot_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            WindowsController.ExitWindows(RestartOptions.Reboot, true);
        }

        private void btnShutdown_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            PerformShutdownAction();
        }

        private void btnShowMenu_Click(object sender, RoutedEventArgs e)
        {
            e.Handled = true;
            cmShutdown.Placement = PlacementMode.Bottom;
            cmShutdown.VerticalOffset = 1;
            cmShutdown.PlacementTarget = btnShutdown;
            cmShutdown.IsOpen = true;
            if (_takeAnActionTimer.IsEnabled)
            {
                Button btnHibernateEdit = (Button)shutdownMenuItem.Template.FindName("btnHibernateEdit", shutdownMenuItem);
                btnHibernateEdit.Content = UIResources.Buttons_Stop;
            }
        }


        private void btnHiberEdit_Click(object sender, RoutedEventArgs e)
        {
            Button btnHibernateEdit = ((Button)sender);

            if ((string)btnHibernateEdit.Content == UIResources.Buttons_Start)
            {
                ShutdownAction();
            }
            else if ((string)btnHibernateEdit.Content == UIResources.Buttons_Stop)
            {
                StopTakeAnActionProgress();
            }
        }

        private void ShutdownAction()
        {
            if (!_takeAnActionTimer.IsEnabled)
                StartTakeAnActionProgress();
            else
                throw new InvalidOperationException("Impossible start already started timer.");
        }

        private void StartTakeAnActionProgress()
        {
            //save initial interval to settings
            Slider slInterval = (Slider)shutdownMenuItem.Template.FindName("slInterval", shutdownMenuItem);
            _timeSpanToAct = TimeSpan.FromMinutes((double)slInterval.Value);
            SettingsManager.CurrentSettings.ActionSpan = _timeSpanToAct;

            //launch timer and animation
            TextBlock lblInterval = (TextBlock)shutdownMenuItem.Template.FindName("lblInterval", shutdownMenuItem);
            Storyboard animation = (Storyboard)shutdownMenuItem.Resources["sbActionInProgress"];
            animation.SetValue(Storyboard.TargetProperty, lblInterval);
            animation.Begin();
            _takeAnActionTimer.Start();

            //update GUI
            Button btnHibernateEdit = (Button)shutdownMenuItem.Template.FindName("btnHibernateEdit", shutdownMenuItem);
            btnHibernateEdit.Content = UIResources.Buttons_Stop;
            cmShutdown.IsOpen = false;
            Grid grdTakeAnActionRoot = (Grid)shutdownMenuItem.Template.FindName("grdTakeAnActionRoot", shutdownMenuItem);
            grdTakeAnActionRoot.IsEnabled = false;
            grdTakeAnActionRoot.IsHitTestVisible = false;
        }

        void _hibernateTimer_Tick(object sender, EventArgs e)
        {
            if (!_timeSpanToAct.HasValue)
                throw new ApplicationException("Timer cannot be started before action span is setup.");

            _timeSpanToAct = _timeSpanToAct.Value - _takeAnActionTimer.Interval;

            //showtime
            if (_timeSpanToAct.Value.TotalMilliseconds <= 0)
            {
                StopTakeAnActionProgress();
                SaveSystemPanelSettings();
                PerformShutdownAction();
            }
            else
            {
                //todo: make via binding
                UpdateActionTimeSpan();
            }
        }

        private void StopTakeAnActionProgress()
        {
            _takeAnActionTimer.Stop();
            Storyboard animation = (Storyboard)shutdownMenuItem.Resources["sbActionInProgress"];
            animation.Stop();
            Button btnHibernateEdit = (Button)shutdownMenuItem.Template.FindName("btnHibernateEdit", shutdownMenuItem);
            btnHibernateEdit.Content = UIResources.Buttons_Start;
            Grid grdTakeAnActionRoot = (Grid)shutdownMenuItem.Template.FindName("grdTakeAnActionRoot", shutdownMenuItem);
            grdTakeAnActionRoot.IsEnabled = true;
            grdTakeAnActionRoot.IsHitTestVisible = true;
        }

        private void UpdateActionTimeSpan()
        {
            if (_takeAnActionTimer.IsEnabled && cmShutdown.IsOpen)
            {
                Slider slInterval = (Slider)shutdownMenuItem.Template.FindName("slInterval", shutdownMenuItem);
                slInterval.Value = _timeSpanToAct.Value.TotalSeconds / 60;
            }
        }

        private void PerformShutdownAction()
        {
#if DEBUG
            MessageBox.Show(string.Format("[{0}] with Force option [{1}] is now could be performed, but this is just a stub.", SettingsManager.CurrentSettings.ShutdownAction.Value, SettingsManager.CurrentSettings.ForceAction.Value ? "enabled" : "disabled"));
#else
            WindowsController.ExitWindows(SettingsManager.CurrentSettings.ShutdownAction.Value, SettingsManager.CurrentSettings.ForceAction.Value);
#endif
        }

        private void btnShutdown_PreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
        {
            //prevent showing context menu
            e.Handled = true;
        }

        private void LoadSystemPanelSettings()
        {
            ComboBox cbShutdownAction = (ComboBox)shutdownMenuItem.Template.FindName("cbShutdownAction", shutdownMenuItem);
            CheckBox cbForceShutdown = (CheckBox)shutdownMenuItem.Template.FindName("cbForceShutdown", shutdownMenuItem);
            Slider slInterval = (Slider)shutdownMenuItem.Template.FindName("slInterval", shutdownMenuItem);
            UserSettings settings = SettingsManager.CurrentSettings;

            //select shutdown type
            string currentShutdownOptions = Constants.RestartOptionsDictionary[(int)settings.ShutdownAction];
            foreach (ComboBoxItem item in cbShutdownAction.Items)
            {
                if (((string)item.Content) == currentShutdownOptions)
                {
                    item.IsSelected = true;
                    break;
                }
            }
            cbForceShutdown.IsChecked = settings.ForceAction;
            _currentScale = settings.ActionSpanScale.Value;
            UpdateSliderCurrentScale();
            slInterval.Value = settings.ActionSpan.Value.TotalMinutes;
        }

        //perform two way biding
        private void SaveSystemPanelSettings()
        {
            UserSettings settings = SettingsManager.CurrentSettings;
            ComboBox cbShutdownAction = (ComboBox)shutdownMenuItem.Template.FindName("cbShutdownAction", shutdownMenuItem);
            CheckBox cbForceShutdown = (CheckBox)shutdownMenuItem.Template.FindName("cbForceShutdown", shutdownMenuItem);
            KeyValuePair<int, string> selectedValue = Constants.RestartOptionsDictionary.FirstOrDefault(i => i.Value == (string)((ComboBoxItem)cbShutdownAction.SelectedItem).Content);
            settings.ShutdownAction = (RestartOptions)selectedValue.Key;
            settings.ForceAction = cbForceShutdown.IsChecked;
            settings.ActionSpanScale = _currentScale;
        }

        private void cmShutdown_Closed(object sender, RoutedEventArgs e)
        {
            SaveSystemPanelSettings();
        }

        private void cmShutdown_Loaded(object sender, RoutedEventArgs e)
        {
            LoadSystemPanelSettings();
            UpdateActionTimeSpan();
        }

        private void ScaleSliderUp_Click(object sender, RoutedEventArgs e)
        {
            if ((int)_currentScale == _timerScalePeriods.Count - 1)
            {
                _currentScale = (TimerScalePeriod)0;
            }
            else
            {
                _currentScale = (TimerScalePeriod)((int)_currentScale + 1);
            }

            UpdateSliderCurrentScale();
        }

        private void ScaleSliderDown_Click(object sender, RoutedEventArgs e)
        {
            if ((int)_currentScale == 0)
            {
                _currentScale = (TimerScalePeriod)_timerScalePeriods.Count - 1;
            }
            else
            {
                _currentScale = (TimerScalePeriod)((int)_currentScale - 1);
            }

            UpdateSliderCurrentScale();
        }

        private void UpdateSliderCurrentScale()
        {
            Slider slInterval = (Slider)shutdownMenuItem.Template.FindName("slInterval", shutdownMenuItem);
            slInterval.Maximum = _timerScalePeriods[(int)_currentScale];
        }
    }
}
